from multiprocessing import Process, Queue

from module.static_module.parent.model import DynamicModule
from module.dynamic_module.k_chart.model.super_model import SuperModel
from module.dynamic_module.k_chart.engine import Engine
from core.constant import *
from tools.framework import get_ui_value

from conf import conf
from datetime import timedelta


class KChartModel(DynamicModule):
    def __init__(self, master):
        super().__init__(master, Module.KChart)
        self.live_file_fixed_time = None

        # k线图接口界面显示的数据
        self.run_mode_ls = []
        # 实时历史共享
        self.data_name_ls = []
        self.symbol_name_ls = []
        self.k_factor_ls = []
        self.vol_factor_ls = []
        self.factor_1_ls = []
        self.factor_2_ls = []
        # 实时

        # 历史
        self.start_time_ls = []
        self.end_time_ls = []
        # 实体类结构变量
        self.run_mode = None
        self.data_name = None
        self.symbol_name = None
        self.k_factor = None
        self.vol_factor = None
        self.factor_1 = None
        self.factor_2 = None
        self.start_time = None
        self.end_time = None

    def sec_init(self):
        self.engine = Engine(self)
        # 加载数据服务模块
        self.run_mode_ls = [o.value for o in DataFlowMode]

        self.data_name_ls = []
        self.symbol_name_ls = []
        self.k_factor_ls = []
        self.vol_factor_ls = []
        self.factor_1_ls = []
        self.factor_2_ls = []

        self.start_time_ls = []
        self.end_time_ls = []

    def on_run_mode_change(self):
        # 根据mode加载相应的属性
        # 更新run_mode
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.RunMode)
        self.run_mode = get_ui_value(values, indices, WidgetCategory.Combobox)
        if not self.run_mode:
            self.run_mode = None
            return
        # 更改实例的实时标志
        if self.run_mode == DataFlowMode.Live.value:
            # 实时数据、历史数据模式下的共有属性
            # 实时数据
            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.MkLive.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFtLive.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFtSgLive.value]
            self.data_name_ls = list(set(self.data_name_ls))
            pass
        elif self.run_mode == DataFlowMode.His.value:
            # 实时数据、历史数据模式下的共有属性
            # 历史数据
            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.Mk.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFt.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFtSg.value]
            pass
        else:
            pass
        # 除数据名称外其他均为空
        self.symbol_name_ls = []
        self.k_factor_ls = []
        self.vol_factor_ls = []
        self.factor_1_ls = []
        self.factor_2_ls = []

        self.start_time_ls = []
        self.end_time_ls = []

    def on_data_name_change(self):
        # 获取数据名并根据是否实盘执行
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.DataName)

        self.data_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        if not self.data_name:
            self.data_name = None
            return
        # 实时数据、历史数据模式下的共有属性
        if conf.DataBridge.own_data_name.value not in self.data_name:
            data_path = self.master.file_manager.describe_all_dc[self.data_name].path
            self.ori_data_dc: dict = self.master.file_manager.read_dc_csv(data_path)
            self.symbol_name_ls = list(self.ori_data_dc.keys())
        else:
            if Module.DataBridge in self.master.dynamic_module_model_dc.keys():
                self.ori_data_dc: dict = self.master.dynamic_module_model_dc[Module.DataBridge].data_dc
            else:
                info = "DataBridge未创建，获取数据失败。"
                self.master.file_manager.log_engine.emit(info, LogName.Running)
                return
            self.symbol_name_ls = list(self.ori_data_dc.keys())
        self.k_factor_ls = []
        self.vol_factor_ls = []
        self.factor_1_ls = []
        self.factor_2_ls = []

        self.start_time_ls = []
        self.end_time_ls = []

    def on_symbol_name_change(self):
        # 获取数据名并根据是否实盘执行
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.SymbolName)

        self.symbol_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        if not self.symbol_name:
            self.symbol_name = None
            return
        # 实时数据、历史数据模式下的共有属性
        # 实时数据由message模块生成，并供K线图模块调用
        ori_data = self.ori_data_dc[self.symbol_name]
        k_columns_ls = ["open", "high", "low", "close", "volume"]
        self.k_factor_ls = [x for x in ori_data.columns if x not in k_columns_ls]
        self.vol_factor_ls = []
        self.factor_1_ls = [x for x in ori_data.columns if x not in conf.KChart.not_factor_ls.value]
        self.factor_2_ls = [x for x in ori_data.columns if x not in conf.KChart.not_factor_ls.value]

        if self.run_mode == DataFlowMode.Live.value:
            self.start_time_ls = [""]
            self.end_time_ls = [""]
            pass
        elif self.run_mode == DataFlowMode.His.value:
            # 历史数据模式下的属性
            if len(ori_data) <= conf.KChart.ori_data_len.value:
                start_time_time = ori_data.index[0]
            else:
                start_time_time = ori_data.index[-conf.KChart.ori_data_len.value]
            end_time_time = ori_data.index[-1]
            # 若两者差距过小则显示的时间具体到分钟，否则具体到日
            if end_time_time - start_time_time < timedelta(days=2):
                self.start_time_ls = [start_time_time.strftime("%Y-%m-%d %H:%M")]
                self.end_time_ls = [end_time_time.strftime("%Y-%m-%d %H:%M")]
            else:
                self.start_time_ls = [start_time_time.strftime("%Y-%m-%d")]
                self.end_time_ls = [end_time_time.strftime("%Y-%m-%d")]
            pass
        else:
            pass
        pass

    @staticmethod
    def start_thread(q: Queue, symbol_name: str):
        # 创建K线图新线程
        super_model = SuperModel()
        super_model.sec_init()
        super_model.set_symbol(symbol_name)
        # 设置通道q
        super_model.set_q(q)
        # 执行work方法
        super_model.work()

    def get_ui_params(self):
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.DataName)
        self.data_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.SymbolName)
        self.symbol_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.KFactor)
        self.k_factor = get_ui_value(values, indices, WidgetCategory.CheckButton)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.VolFactor)
        self.vol_factor = get_ui_value(values, indices, WidgetCategory.CheckButton)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.Factor1)
        self.factor_1 = get_ui_value(values, indices, WidgetCategory.CheckButton)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.Factor2)
        self.factor_2 = get_ui_value(values, indices, WidgetCategory.CheckButton)

        # 历史数据模式下的属性
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.StartTime)
        self.start_time = get_ui_value(values, indices, WidgetCategory.Entry)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(LabelMember.EndTime)
        self.end_time = get_ui_value(values, indices, WidgetCategory.Entry)

    def on_ok_thread(self):
        # try:
        # 从ui界面获取参数信息
        self.get_ui_params()

        self.engine.loop()

        # 创建K线图主窗口及其下一级所有窗口，采用新进程的方式
        # except Exception as e:
        #     info = f"任务运行出错，错误信息{e}")
        #     pass
        # 任务结束
        self.task_end()
        pass

    def on_stop(self):
        if self.engine.data_server is None:
            info = "数据服务实例不存在。"
            self.master.file_manager.log_engine.emit(info, LogName.Running)
        else:
            self.engine.set_is_end(True)
            info = "已发出终止数据流信号。"
            self.master.file_manager.log_engine.emit(info, LogName.Running)


